本篇我們將實作音視訊的錄製並下載,內容包含:
錄製影片
回放影片
下載影片
複製上一篇程式碼
cp -r take-a-photo video-recording
index.html 中 將 video play 及 button 替換為以下
<div><video autoplay playsinline id="player"></video></div>
<div><button id="shoot">拍照</button></div>
替換為
<div>
  <video autoplay playsinline id="player"></video>
  <video autoplay id="replayer"></video>
</div>
<div>
  <button id="shoot">拍照</button>
  <button id="record">錄影</button>
  <button id="replay" disabled>回放</button>
  <button id="download" disabled>下載</button>
</div>
錄影、 回放 、 下載
main.js 實作
在原本的方法中增加 window.stream = stream
// 將視訊顯示在 video 標籤上
function gotStream(stream) {
  videoElement.srcObject = stream
+  window.stream = stream  // 增加這段,錄影需要取得stream
  return navigator.mediaDevices.enumerateDevices()
}
在後面加上錄影的程式碼:
//record
let buffer
let mediaRecorder
const recvideo = document.querySelector('video#replayer');
const btnRecord = document.querySelector('button#record');
const btnPlay = document.querySelector('button#replay');
const btnDownload = document.querySelector('button#download');
function handleDataAvailable(e) {
  if (e && e.data && e.data.size > 0) {
    buffer.push(e.data)
  }
}
function startRecord() {
  buffer = []
  var options = {
    mimeType: 'video/webm;codecs=vp8',
  }
  if (!MediaRecorder.isTypeSupported(options.mimeType)) {
    console.error(`${options.mimeType} is not supported!`)
    return
  }
  try {
    mediaRecorder = new MediaRecorder(window.stream, options)
  } catch (e) {
    console.error('Failed to create MediaRecorder:', e)
    return
  }
  mediaRecorder.ondataavailable = handleDataAvailable
  mediaRecorder.start(10)
}
function stopRecord() {
  mediaRecorder.stop()
}
btnRecord.onclick = () => {
  if (btnRecord.textContent === '錄影') {
    startRecord()
    btnRecord.textContent = '停止'
    btnPlay.disabled = true
    btnDownload.disabled = true
  } else {
    stopRecord()
    btnRecord.textContent = '錄影'
    btnPlay.disabled = false
    btnDownload.disabled = false
  }
}
btnPlay.onclick = () => {
  var blob = new Blob(buffer, { type: 'video/webm' })
  recvideo.src = window.URL.createObjectURL(blob)
  recvideo.srcObject = null
  recvideo.controls = true
  recvideo.play()
}
btnDownload.onclick = () => {
  var blob = new Blob(buffer, { type: 'video/webm' })
  var url = window.URL.createObjectURL(blob)
  var a = document.createElement('a')
  a.href = url
  a.style.display = 'none'
  a.download = 'video.webm'
  a.click()
}
可以在瀏覽器的 console 中輸入以下
function getSupportedMimeTypes() {
  const VIDEO_TYPES = ['webm', 'ogg', 'mp4', 'x-matroska']
  const VIDEO_CODECS = [
    'vp9', 'vp9.0', 'vp8', 'vp8.0', 'avc1', 'av1',
    'h265', 'h.265', 'h264', 'h.264', 'opus'
  ]
  const supportedTypes = []
  VIDEO_TYPES.forEach((videoType) => {
    const type = `video/${videoType}`
    VIDEO_CODECS.forEach((codec) => {
      const variations = [
        `${type};codecs=${codec}`,
        `${type};codecs:${codec}`,
        `${type};codecs=${codec.toUpperCase()}`,
        `${type};codecs:${codec.toUpperCase()}`,
        `${type}`,
      ]
      variations.forEach((variation) => {
        if (MediaRecorder.isTypeSupported(variation))
          supportedTypes.push(variation)
      })
    })
  })
  return supportedTypes
}
const supportedMimeTypes = getSupportedMimeTypes()
console.log('Best supported mime types by priority : ', supportedMimeTypes[0])
console.log(
  'All supported mime types ordered by priority : ',
  supportedMimeTypes,
)